package com.example.shuiyin.service;

import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * MinIO存储服务接口
 */
public interface MinioStorageService {

    /**
     * 上传文件到MinIO
     * 
     * @param file 文件数据
     * @param objectName 对象名称/路径
     * @return 访问URL
     * @throws IOException 如果上传过程中发生错误
     */
    String uploadFile(MultipartFile file, String objectName) throws IOException;
    
    /**
     * 上传文件到指定桶
     * 
     * @param file 文件数据
     * @param bucketName 存储桶名称
     * @param objectName 对象名称/路径
     * @return 访问URL
     * @throws IOException 如果上传过程中发生错误
     */
    String uploadFile(MultipartFile file, String bucketName, String objectName) throws IOException;
    
    /**
     * 获取预签名URL用于访问文件
     * 
     * @param objectName 对象名称/路径
     * @return 预签名URL
     */
    String getPreSignedUrl(String objectName);
    
    /**
     * 获取指定桶中文件的预签名URL
     * 
     * @param bucketName 存储桶名称
     * @param objectName 对象名称/路径
     * @return 预签名URL
     */
    String getPreSignedUrl(String bucketName, String objectName);
    
    /**
     * 删除文件
     * 
     * @param objectName 对象名称/路径
     * @return 是否删除成功
     */
    boolean deleteFile(String objectName);
    
    /**
     * 删除指定桶中的文件
     * 
     * @param bucketName 存储桶名称
     * @param objectName 对象名称/路径
     * @return 是否删除成功
     */
    boolean deleteFile(String bucketName, String objectName);
    
    /**
     * 列出目录下的所有文件
     * 
     * @param prefix 前缀/目录
     * @return 文件对象列表
     */
    List<String> listFiles(String prefix);
    
    /**
     * 确保桶存在
     * @param bucketName 桶名称
     * @throws IOException 如果操作失败
     */
    void ensureBucketExists(String bucketName) throws IOException;
    
    /**
     * 检查对象是否存在（在默认桶中）
     * @param objectName 对象名称
     * @return 是否存在
     */
    boolean objectExists(String objectName);
    
    /**
     * 检查对象是否存在（在指定桶中）
     * @param bucketName 桶名称
     * @param objectName 对象名称
     * @return 是否存在
     */
    boolean objectExists(String bucketName, String objectName);
    
    /**
     * 从默认桶中删除对象
     * @param objectName 对象名称
     * @throws IOException 如果删除失败
     */
    void deleteObject(String objectName) throws IOException;
    
    /**
     * 从指定桶中删除对象
     * @param objectName 对象名称
     * @param bucketName 桶名称
     * @throws IOException 如果删除失败
     */
    void deleteObject(String objectName, String bucketName) throws IOException;
    
    /**
     * 获取对象（从默认桶）
     * @param objectName 对象名称
     * @return 输入流
     * @throws IOException 如果获取失败
     */
    InputStream getObject(String objectName) throws IOException;
    
    /**
     * 获取对象（从指定桶）
     * @param bucketName 桶名称
     * @param objectName 对象名称
     * @return 输入流
     * @throws IOException 如果获取失败
     */
    InputStream getObject(String bucketName, String objectName) throws IOException;
    
    /**
     * 上传头像
     * @param file 头像文件
     * @param userId 用户ID
     * @param filename 文件名
     * @return 头像URL
     * @throws IOException 如果上传失败
     */
    String uploadAvatar(MultipartFile file, Long userId, String filename) throws IOException;
    
    /**
     * 获取文件URL
     * @param bucketName 桶名称
     * @param objectName 对象名称
     * @return 文件URL
     */
    String getFileUrl(String bucketName, String objectName);

    /**
     * 生成预签名URL用于访问对象
     * @param bucketName 桶名称
     * @param objectName 对象名称
     * @param expirySeconds URL有效期(秒)
     * @return 预签名URL
     */
    String generatePresignedUrl(String bucketName, String objectName, int expirySeconds);

    /**
     * 清理测试文件
     * @param prefix 文件前缀，例如"test/"或"temp/"
     * @return 清理的文件数量
     */
    int cleanupTestFiles(String prefix);

    /**
     * 清理指定桶中的测试文件
     * @param bucketName 桶名称
     * @param prefix 文件前缀，例如"test/"或"temp/"
     * @return 清理的文件数量
     */
    int cleanupTestFiles(String bucketName, String prefix);

    /**
     * 清理所有测试文件(包括测试桶)
     * @return 清理的文件数量
     */
    int cleanupAllTestFiles();

    /**
     * 将文件作为资源加载
     * 
     * @param objectName 对象名称/文件路径
     * @return 包含文件的资源对象
     */
    Resource loadFileAsResource(String objectName);
    
    /**
     * 从文件路径上传文件到存储并返回访问URL
     * @param filePath 文件路径
     * @param fileName 文件名
     * @param objectName 对象名称
     * @return 文件访问URL
     * @throws IOException 如果上传过程中发生I/O错误
     */
    String uploadFile(String filePath, String fileName, String objectName) throws IOException;
} 